package com.nbstar.film.spider.http;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.zip.GZIPInputStream;

public class HttpRequest {

    /**
     * 从输入流中获取字节数组
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static  byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    public static byte[] httpsGetBin(String url) {
        HttpsURLConnection conn = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.connect();
            InputStream inputStream = conn.getInputStream();
            byte[] out = readInputStream(inputStream);
            return out;
        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return null;
    }

    public static String httpsGet(String url, Map<String, String> header){
        //String str_return = "";
        StringBuilder result = new StringBuilder();
        HttpsURLConnection conn = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            for(Map.Entry<String, String> entry : header.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.connect();
            InputStream is = conn.getInputStream();

            InputStream stream = new GZIPInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
            String line = "";
            while ((line = reader.readLine()) != null){
                result.append(line + "\r\n");
            }


        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return result.toString();
    }


    public static String httpsGetUnzip(String url, Map<String, String> header){
        //String str_return = "";
        StringBuilder result = new StringBuilder();
        HttpsURLConnection conn = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            for(Map.Entry<String, String> entry : header.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            conn.connect();
            InputStream is = conn.getInputStream();

            InputStream stream = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
            String line = "";
            while ((line = reader.readLine()) != null){
                result.append(line + "\r\n");
            }


        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return result.toString();
    }

    /**
     * https get请求
     * @param url
     * @return
     */
    public static String httpsGet(String url){
        //String str_return = "";
        StringBuilder result = new StringBuilder();
        HttpsURLConnection conn = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
            conn.setRequestProperty("Cache-Control", "max-age=0");
            conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
            conn.connect();
            InputStream is = conn.getInputStream();

            InputStream stream = new GZIPInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
            String line = "";
            while ((line = reader.readLine()) != null){
                result.append(line + "\r\n");
            }

//            BufferedReader br = new BufferedReader(new InputStreamReader(is,
//                    ("ISO-8859-1")));
//            String ret = "";
//            while (ret != null) {
//                ret = br.readLine();
//                if (ret != null && !ret.trim().equals("")) {
//                    str_return = str_return
//                            + new String(ret.getBytes("ISO-8859-1"), "utf-8") + "\r\n";
//                }
//            }
        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return result.toString();
    }
    /**
     * https Post请求
     * @param url
     * @return
     */
    public static String httpsPost(String url,Map parameters){
        String str_return = "";
        HttpsURLConnection conn = null;
        try {
            StringBuffer params = new StringBuffer();
            for (Iterator iter = parameters.entrySet().iterator(); iter.hasNext();){
                Map.Entry element = (Map.Entry) iter.next();
                params.append(element.getKey().toString());
                params.append("=");
                params.append(URLEncoder.encode(element.getValue().toString(),"utf-8"));
                params.append("&");
            }

            if (params.length() > 0) {
                params = params.deleteCharAt(params.length() - 1);
            }

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
            URL console = new URL(url);
            conn = (HttpsURLConnection) console.openConnection();
            conn.setRequestMethod("POST");
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.setDoOutput(true);
            byte[] b = params.toString().getBytes();
            conn.getOutputStream().write(b, 0, b.length);
            conn.getOutputStream().flush();
            conn.getOutputStream().close();

            conn.connect();
            InputStream is = conn.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(is,
                    ("ISO-8859-1")));
            String ret = "";
            while (ret != null) {
                ret = br.readLine();
                if (ret != null && !ret.trim().equals("")) {
                    str_return = str_return
                            + new String(ret.getBytes("ISO-8859-1"), "utf-8");
                }
            }
        } catch (ConnectException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return str_return;
    }

    public static String maoYanGetFilmInfo(String requestUrl) {


        Map<String, String> header = new HashMap<>();
        header.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
        header.put("Accept-Encoding", "gzip, deflate, br");
        header.put("Accept-Language", "zh-CN,zh;q=0.9");
        header.put("Referer", "https://maoyan.com/?channel=touch_group");
        header.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
        //header.put("Cookie", "__mta=222067623.1594826118126.1595084192354.1595084252730.32; uuid_n_v=v1; uuid=F941C3A0C6AD11EAA3247117811965ECCF293342A58048F58D532A0EF80CE081; _lxsdk_cuid=173530b2c22c8-062d599ddabdc-3e385e0c-100200-173530b2c23c8; _lxsdk=F941C3A0C6AD11EAA3247117811965ECCF293342A58048F58D532A0EF80CE081; mojo-uuid=e4f4ee89e9b52161439f705011c22527; _csrf=465dd873a9d42142d73b708681fe90b904460ab980356d74ebfb1bb0189e96e6; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1595123571,1595138902,1595155679,1595212417; _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; Hm_lpvt_703e94591e87be68cc8da0da7cbd0be2=1595212786; __mta=222067623.1594826118126.1595084252730.1595212786597.33; _lxsdk_s=1736a9d4b6d-bb9-bfe-372%7C%7C3");
        header.put("Cookie", "__mta=222067623.1594826118126.1595084192354.1595084252730.32; uuid_n_v=v1; uuid=F941C3A0C6AD11EAA3247117811965ECCF293342A58048F58D532A0EF80CE081; _lxsdk_cuid=173530b2c22c8-062d599ddabdc-3e385e0c-100200-173530b2c23c8; _lxsdk=F941C3A0C6AD11EAA3247117811965ECCF293342A58048F58D532A0EF80CE081; mojo-uuid=e4f4ee89e9b52161439f705011c22527; _csrf=465dd873a9d42142d73b708681fe90b904460ab980356d74ebfb1bb0189e96e6; Hm_lvt_703e94591e87be68cc8da0da7cbd0be2=1595123571,1595138902,1595155679,1595212417; _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; _lxsdk_s=1736af6d10c-67d-7ac-438%7C%7C1");
        String ip = "192.168.";
        Random rand = new Random();
        ip += rand.nextInt(254) + "." + rand.nextInt(254);
        //header.put("x-forwarded-for", ip);
        String html = new String(HttpRequest.httpGet(requestUrl, header, true));

        return  html;

//
//        HttpURLConnection conn = null;
//        InputStream is = null;
//        BufferedReader br = null;
//        StringBuilder result = new StringBuilder();
//
//        try{
//            //创建远程url连接对象
//            java.net.URL url = new URL(requestUrl);
//            //通过远程url连接对象打开一个连接，强转成HTTPURLConnection类
//            conn = (HttpURLConnection) url.openConnection();
//            conn.setRequestMethod("GET");
//            //conn.setInstanceFollowRedirects(false);
//            //设置连接超时时间和读取超时时间
//            //conn.setConnectTimeout(15000);
//            conn.setReadTimeout(60000);
//            conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
//            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
//            conn.setRequestProperty("Connection", "keep-alive");
//            conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
//            conn.setRequestProperty("Cache-Control", "max-age=0");
//            conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
//            //发送请求
//            conn.connect();
//
//            //通过conn取得输入流，并使用Reader读取
//
//            System.out.println("response code:" + conn.getResponseCode());
//
//
//            if (200 == conn.getResponseCode()){
//                //System.out.println("Code==200");
//
//                InputStream stream = new GZIPInputStream(conn.getInputStream());
//                BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
//                String line = "";
//                while ((line = reader.readLine()) != null){
//                    result.append(line + "\r\n");
//                }
//
//
//            }
//        }catch (MalformedURLException e){
//            e.printStackTrace();
//        }catch (IOException e){
//            e.printStackTrace();
//        }catch (Exception e){
//            e.printStackTrace();
//        }finally {
//            try{
//                if(br != null){
//                    br.close();
//                }
//                if(is != null){
//                    is.close();
//                }
//            }catch (IOException ioe){
//                ioe.printStackTrace();
//            }
//            conn.disconnect();
//        }
//        return result.toString();
    }

    public static byte[] httpGet(String requestUrl, Map<String, String> headers, boolean unzip) {
        HttpURLConnection conn = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuilder result = new StringBuilder();

        try{
            //创建远程url连接对象
            URL url = new URL(requestUrl);
            //通过远程url连接对象打开一个连接，强转成HTTPURLConnection类
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            //conn.setInstanceFollowRedirects(false);
            //设置连接超时时间和读取超时时间
            //conn.setConnectTimeout(15000);
            conn.setReadTimeout(60000);

            if (null != headers) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            //发送请求
            conn.connect();

            //通过conn取得输入流，并使用Reader读取
            System.out.println("response code:" + conn.getResponseCode());
            if (200 == conn.getResponseCode()){
                //System.out.println("Code==200");

                Map<String, List<String>> map = conn.getHeaderFields();
                // 遍历所有的响应头字段
//                for (String key : map.keySet()) {
//                    System.out.println(key + "--->" + map.get(key));
//                }

                InputStream stream = null;
                if (unzip) {
                    stream = new GZIPInputStream(conn.getInputStream());

//                    if (map.get("Content-Encoding") != null &&  map.get("Content-Encoding").toString().trim().contains("gzip")) {
//                        stream = new GZIPInputStream(conn.getInputStream());
//                    } else {
//                        stream = conn.getInputStream();
//                    }
                    BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "utf-8"));
                    String line = "";
                    while ((line = reader.readLine()) != null) {
                        result.append(line + "\r\n");
                    }
                } else {
                    byte[] out = readInputStream(stream);
                    return out;
                }

            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(br != null){
                    br.close();
                }
                if(is != null){
                    is.close();
                }
            }catch (IOException ioe){
                ioe.printStackTrace();
            }
            conn.disconnect();
        }
        return result.toString().getBytes();
    }

//    public static String maoYanGet(String requestUrl) {
//        HttpURLConnection conn = null;
//        InputStream is = null;
//        BufferedReader br = null;
//        StringBuilder result = new StringBuilder();
//
//        try{
//            //创建远程url连接对象
//            java.net.URL url = new URL(requestUrl);
//            //通过远程url连接对象打开一个连接，强转成HTTPURLConnection类
//            conn = (HttpURLConnection) url.openConnection();
//            conn.setRequestMethod("GET");
//            conn.setInstanceFollowRedirects(false);
//            //设置连接超时时间和读取超时时间
//            //conn.setConnectTimeout(15000);
//            conn.setReadTimeout(60000);
//            conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
//            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
//            conn.setRequestProperty("Connection", "keep-alive");
//            conn.setRequestProperty("Upgrade-Insecure-Requests", "1");
//            conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
//            conn.setRequestProperty("x-forwarded-for", "192.168.3.31");
//
//            //发送请求
//            conn.connect();
//
//            //通过conn取得输入流，并使用Reader读取
//
//            if (200 == conn.getResponseCode()){
//                //System.out.println("Code==200");
//
//                InputStream stream = new GZIPInputStream(conn.getInputStream());
//                BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
//                String line = "";
//                while ((line = reader.readLine()) != null){
//                    result.append(line + "\r\n");
//                }
//
//
////                is = conn.getInputStream();
////                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
////                String line;
////                System.out.println("dddddddddddddddddd");
////                Map<String, List<String>> map = conn.getHeaderFields();
////                // 遍历所有的响应头字段
////                for (String key : map.keySet()) {
////                    System.out.println(key + "--->" + map.get(key));
////                }
////                System.out.println("ooooooooooooooooooooo");
////
////                while ((line = br.readLine()) != null){
////                    result.append(line + "\r\n");
////
////                    //System.out.println(line);
////
////                }
//            }
//        }catch (MalformedURLException e){
//            e.printStackTrace();
//        }catch (IOException e){
//            e.printStackTrace();
//        }catch (Exception e){
//            e.printStackTrace();
//        }finally {
//            try{
//                if(br != null){
//                    br.close();
//                }
//                if(is != null){
//                    is.close();
//                }
//            }catch (IOException ioe){
//                ioe.printStackTrace();
//            }
//            conn.disconnect();
//        }
//        return result.toString();
//    }

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url;
            if (null != param) {
                urlNameString = url + "?" + param;
            }
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
            //connection.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
            //connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
            //connection.setRequestProperty("Cache-Control", "max-age=0");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
//            for (String key : map.keySet()) {
//                System.out.println(key + "--->" + map.get(key));
//            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line + "\r\n";
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
}
